﻿// Глобальная конфигурация
//
var globalConfig = {
    /*language: 'english',
    defaults: {
        enableGeolocation: true,
        enableSharing: false,
        maxPhotos: 20
    },
    theme: {
        skin: 'a',
        toolbars: {
            index: 'ui-navigation-toolbar',
            pages: 'ui-custom-toolbar'
        }
    },*/
    defaults: {
        enableCentering: true,
        // задержка таймера в мс
        intervalTimerDelay: 10000,
    },
    mapOptions: {
        // масштаб (0..22)
        mapZoom: 8,
        // центр карты
        mapCenter: { lat: 53.315076, lng: 28.238 }, // географический центр Беларуси
        // панорамный вид
        streetViewControl: false, // панорамный вид не требуется
        // показывать шкалу масштаба
        scaleControl: true, // показать шкалу масштаба
        // тип карты по умолчанию (HYBRID/ROADMAP/SATELLITE/TERRAIN) 
        mapType: 'ROADMAP' // тип карты по умолчанию 
    },
    polylineOptions: {
        color: "00FF00",
        opacity: 0.4,
        weight: 2,
        icon: {
            path: 'M -.25,-.25 .25,-.25, .25,.25 -.25,.25',
            opacity: 0.4,
            color: 'blue',
            repeat: '6px',
        }
    },
    polygonOptions: {
        borderColor: "00FF00",
        borderOpacity: 1.0,
        borderWeight: 2,
        fillColor: "00FF00",
        fillOpacity: 0.5,
        editable: false,
    },
    markerOptions: {
        // позиция маркера на карте
        //latlng: { x: 0, y: 0 },
        // анимация при добавлении маркера на карту (BOUNCE/DROP)
        animation: null,
        // маркер реагирует или нет на нажатия мыши 
        clickable: true,
        // курсор, отображаемый при наведении на маркер
        cursor: "pointer",
        // маркер можно/нельзя перетаскивать
        draggable: false,
        // текстовая надпись поверх маркера
        title: '',
        // параметры изображения для маркера
        icon: {
            // размер иконки
            size: { w: 66, h: 28 },
            // смещение относительно верхнего левого угла
            origin: { x: 0, y: 0 },
            // точка крепления иконки на карте
            anchor: { x: 33, y: 28 },
            // URL-адрес, по которому находится иконка
            urlPath: {
                actual: "/Images/CarLogo/truckBelAZ_new.png",
                actualOutside: "/Images/CarLogo/truckBelAZ_new_out.png",
                outdated: "/Images/CarLogo/truckBelAZ_old.png",
                outdatedOutside: "/Images/CarLogo/truckBelAZ_old_out.png"
            }
        }
    }
};

/* ----- GMapManager -----*/
(function () {

    // Функциональное объявление класса GMapManager
    //
    monitor.GMapManager = function (mapDivId, enableIntervalTimer) {
        var map; // карта
        var carMarkers = []; // машины
        var areaPolygons = []; // зоны
        var carLogos = []; // коллекция логотипов машин
        var infowindow; // информационное окно (одно на все машины)
        var drawingArea; // рисуемая зона (не более одной одновременно)
        var isDrawingMode = false; // true - активен режим рисования зоны
        // содержимое информационного окна 
        var infoContent = "<h3>{%}</h3>" +
            "<i>{%}</i><br/>" +
            "<u>Широта</u>: <i><span id='lat'>{%}</span></i><br/>" +
            "<u>Долгота</u>: <i><span id='lng'>{%}</span></i><br/>" +
            "<u>Дата</u>: <i><span id='date'>{%}</span></i><br/><br/>";
        var timerId; // идентификатор запущенного таймера
        var timerDelay = 5000; // по умолчанию задержка таймера 5 с 
        var outdatedInterval = 1000 * 60 * 10; // по истечении 10 мин информация считается устаревшей

        enableIntervalTimer = (typeof enableIntervalTimer == 'undefined')
            ? true // по умолчанию
            : enableIntervalTimer; // передан в параметрах
        initialize(); // начальная инициализация

        // ---------- приватные методы ----------

        // Инициализация.

        function initialize() {
            var cfgMapOpts = globalConfig.mapOptions || {}; // сокращенное имя глобальных параметров карты
            var mapOptions = {
                mapZoom: cfgMapOpts.mapZoom,
                mapCenter: cfgMapOpts.mapCenter,
                streetViewControl: cfgMapOpts.streetViewControl,
                scaleControl: cfgMapOpts.scaleControl,
                mapType: cfgMapOpts.mapType
            }; // параметры создания карты
            map = new monitor.gmap.Map(mapDivId, mapOptions); // создание карты

            carLogos['actual'] = getCarLogoImage('actual');
            carLogos['actualOutside'] = getCarLogoImage('actualOutside');
            carLogos['outdated'] = getCarLogoImage('outdated');
            carLogos['outdatedOutside'] = getCarLogoImage('outdatedOutside');

            infowindow = new monitor.gmap.InfoWindow();

            map.on('click', function () {
                infowindow.close();
            });

            if (enableIntervalTimer) {
                var cfgDefaults = globalConfig.defaults || {};
                timerDelay = cfgDefaults.intervalTimerDelay || timerDelay;
                startIntervalTimer();
            }
        }

        // Получить изображение для маркера машины.
        function getCarLogoImage(category) {
            if ((typeof (category) == "undefined") || (category == null)) {
                category = "actual";
            }
            if (!carLogos[category]) {
                var cfgMarkerIconOpts = globalConfig.markerOptions.icon || {}; // сокращенное имя глобальных параметров 
                // изображения маркера
                var markerIconOptions = {
                    urlPath: cfgMarkerIconOpts.urlPath[category],
                    size: cfgMarkerIconOpts.size,
                    origin: cfgMarkerIconOpts.origin,
                    anchor: cfgMarkerIconOpts.anchor
                }; // параметры задания иконки для маркера

                carLogos[category] = new monitor.gmap.MarkerIcon(markerIconOptions);
            }
            return carLogos[category];
        }

        function createCarMarker() {
            var marker = null;
            var markerOpts = {
                map: map, // обязательный параметр
                latlng: globalConfig.markerOptions.latlng,
                title: globalConfig.markerOptions.title,
                animation: globalConfig.markerOptions.animation,
                draggable: globalConfig.markerOptions.draggable,
                clickable: globalConfig.markerOptions.clickable,
                cursor: globalConfig.markerOptions.cursor
            };
            marker = new monitor.gmap.Marker(markerOpts);
            //marker.setInfoWindow(infowindow);
            //marker.checked = false;
            marker.infoContent = document.createElement('div');
            marker.numCopies = 0;
            //marker.areasHits = 0;
            marker.areasId = [];
            marker.on('click', function () {
                infowindow.setInfoContent(marker.infoContent);
                infowindow.open(map.googleMap, marker.googleMarker);
            });
            return marker;
        }

        function updateCarInfo(carId, latlng, dateReg) {
            if (carMarkers[carId]) {
                setInfoContentElement(carMarkers[carId].infoContent, 'lat', latlng.x + '');
                setInfoContentElement(carMarkers[carId].infoContent, 'lng', latlng.y + '');
                setInfoContentElement(carMarkers[carId].infoContent, 'date', constructDateString(dateReg));
                setIconByDateRelevance(carId, dateReg);
                carMarkers[carId].setPosition(latlng);
            }
        }

        function setIconByDateRelevance(carId, dateReg) {
            if ((new Date() - dateReg) > outdatedInterval) {
                carMarkers[carId].setIcon(carLogos['outdated']);
            } else {
                carMarkers[carId].setIcon(carLogos['actual']);
            }
        }

        function updateCarMarkers() {
            var arrayStr;
            var carIdArr = [];
            for (var id in carMarkers) {
                if (carMarkers[id].numCopies > 0) {
                    carIdArr.push(id);
                }
            }
            if (carIdArr.length == 0) {
                return;
            }
            var carIdStr = 'listOfId=' + carIdArr.join('&listOfId=');

            // Запрос на получение данных сразу о всех выбранных машинах.
            $.ajax({
                url: '/data/CarsPosition/',
                data: carIdStr,
                cache: true,
                type: 'GET',
                contentType: 'application/json; charset=utf-8',
                success: function (carOutput) {
                    if (carOutput) {
                        for (var i = 0; i < carOutput.length; i++) {
                            if (carOutput[i].CarCoords) {
                                var carId = carOutput[i].CarId;
                                var latlng = { x: carOutput[i].CarCoords.X, y: carOutput[i].CarCoords.Y };
                                var dateReg = new Date(carOutput[i].CarCoords.Date + 'Z');
                                updateCarInfo(carId, latlng, dateReg);
                            }
                        }
                    }
                },
                error: function (e) {
                    alert(e.responseText);
                }
            });
        }

        // Вспомогательная функция по обновлению элемента информационного окна,
        // если оно содержит DOM-структуру.

        function setInfoContentElement(infoContent, elemId, text) {
            var elements = infoContent.getElementsByTagName('span');
            if (elements[elemId]) {
                elements[elemId].textContent = text;
            }
        }

        // Получение строки времени требуемого формата.

        function constructDateString(retrievedDate) {
            var year = retrievedDate.getFullYear();
            var month = ('0' + (retrievedDate.getMonth() + 1)).slice(-2);
            var day = ('0' + retrievedDate.getDate()).slice(-2);
            var hours = retrievedDate.getHours();
            var minutes = ('0' + retrievedDate.getMinutes()).slice(-2);
            var dateStr = year + "-" + month + "-" + day + " " + hours + ":" + minutes;
            return dateStr;
        }

        // Запустить интервальный таймер.

        function startIntervalTimer() {
            // Таймер срабатывает через промежутки времени timerDelay.
            timerId = setInterval(function () {
                // Периодическое обновление сведений о выбранных машинах.
                updateCarMarkers();
            }, timerDelay);
        }

        // Остановить интервальный таймер.

        function stopIntervalTimer() {
            clearInterval(timerId);
        }


        // ---------- публичные методы ----------

        // Возвращает факт наличия машины во внутренней коллекции.
        this.isCarAdded = function (carId) {
            return ((typeof carMarkers[carId] == "undefined") || (carMarkers[carId] == null)) ?
                false : true;
        };
        // Возвращает факт наличия зоны во внутренней коллекции.
        this.isAreaAdded = function (areaId) {
            return ((typeof areaPolygons[areaId] == "undefined") || (areaPolygons[areaId] == null)) ?
                false : true;
        };
        // Добавить машину во внутреннюю коллекцию.
        this.addCar = function (carId, args) {
            // Создать маркер, если он еще не был создан.
            if (!carMarkers[carId]) {
                // Создание маркера на карте без указания его позиции.
                carMarkers[carId] = createCarMarker();
                if ((typeof args != "undefined") && (args != null)) {
                    carMarkers[carId].infoContent.innerHTML = infoContent.format([args.name, args.comment]);
                    if (args.latlng && args.dateReg) {
                        updateCarInfo(carId, args.latlng, args.dateReg);
                    }
                }
            }
        };
        // Показать машину на карте.
        this.showCar = function (carId, areaId) {
            if (!carMarkers[carId].numCopies++) {
                carMarkers[carId].show();
            }
            if ((typeof areaId != "undefined") && (areaId != null)) {
                carMarkers[carId].areasId.push(areaId);
            }
        };
        // Скрыть машину с карты.
        this.hideCar = function (carId, areaId) {
            if (carMarkers[carId] && !--carMarkers[carId].numCopies) {
                carMarkers[carId].hide();
            }
            if ((typeof areaId != "undefined") && (areaId != null)) {
                var indexToDelete = carMarkers[carId].areasId.indexOf(areaId);
                if (~indexToDelete) {
                    carMarkers[carId].areasId.splice(indexToDelete, 1);
                }
            }
        };
        // Удалить машину из внутренней коллекции.
        this.removeCar = function (carId, areaId) {
            console.log('removing car...');
        };

        // Добавить зону на карту.
        this.addArea = function (areaId, areaCoords) {
            var areaOptions = {
                map: map, // обязательный параметр
                borderColor: globalConfig.polygonOptions.borderColor,
                borderOpacity: globalConfig.polygonOptions.borderOpacity,
                borderWeight: globalConfig.polygonOptions.borderWeight,
                fillColor: globalConfig.polygonOptions.fillColor,
                fillOpacity: globalConfig.polygonOptions.fillOpacity
            }; // параметры создания карты
            areaPolygons[areaId] = new monitor.gmap.AreaPoly(areaOptions);
            areaPolygons[areaId].shapeArea(areaCoords);
            areaPolygons[areaId].show();
        };
        // Убрать зону с карты.
        this.removeArea = function (areaId) {
            areaPolygons[areaId].clearArea();
        };

        // Перерисовать карту по размеру содержащего ее HTML-контейнера.
        this.resize = function () {
            // вызвать событие карты 'resize'
            map.trigger('resize');
        };

        this.startDrawing = function () {
            this.clearDrawing();
            drawingArea = new monitor.DrawingArea({ map: map });
            //if (!isDrawingMode) {
            //    isDrawingMode = true;
            //var self = this;
            //var timeout = null;

            map.setMapCursor('crosshair');
            //this.map.setOptions({ disableDoubleClickZoom: true});

            //this.areaObj.areaPoly.setOptions({ strokeWeight: 0, editable: true });
            //this.stPoint = null;

            /*map.on('click', function(mouseEvent) {
                drawingArea.addNextVertex(mouseEvent.coord);
            });
            map.on('mousemove', function (mouseEvent) {
                drawingArea.moveHintLine(mouseEvent.coord);
            });*/
            //drawingArea.onDrawingMode();
            /*if (this.areaObj.dottedLine) {
                this.eventListeners["dotted_click"] = google.maps.event.addListener(this.areaObj.dottedLine, 'click', function (mouseEvent) {
                    google.maps.event.trigger(self.map, 'click', mouseEvent);
                });
               
                this.eventListeners["dotted_rightclick"] = google.maps.event.addListener(this.areaObj.dottedLine, 'rightclick', function (mouseEvent) {
                    google.maps.event.trigger(self.map, 'rightclick', mouseEvent);
                });
            }*/
            //}
        };
        this.endDrawing = function () {
            //if (isDrawingMode) {
            //    isDrawingMode = false;

            map.setMapCursor('default');
            //this.stPoint = null;

            /*map.off('click', function (mouseEvent) {
                drawingArea.addNextVertex(mouseEvent.coord);
            });
            map.off('mousemove', function (mouseEvent) {
                drawingArea.moveHintLine(mouseEvent.coord);
            });*/
            if (drawingArea)
                drawingArea.stop();

            /*if (this.areaObj.dottedLine) {
                google.maps.event.removeListener(this.eventListeners["dotted_click"]);
                google.maps.event.removeListener(this.eventListeners["dotted_dblclick"]);
                google.maps.event.removeListener(this.eventListeners["dotted_rightclick"]);
            };*/

            //this.clearOverlays(["border", "dotted", "markers"]);
            //this.areaObj.areaPoly.setOptions({ strokeWeight: 2 });
            //this.fire("end_drawing");
            //}
        };
        this.clearDrawing = function () {
            if (drawingArea)
                drawingArea.clearOverlays();
            //drawingArea = null;
        };
        this.getDrawingAreaCoords = function() {
            var coords = [];
            if (drawingArea) {
                coords = drawingArea.getCoords();
            }
            return coords;
        };
    };
})();